<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  <title>nodejs | Hexo</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta name="description" content="搭建博客案例基本结构并渲染首页 把MVC结构搭建起来  用户注册模块的实现用户登录模块的实现登录密码MD5加密存储的实现为什么要对密码进行加密处理在现实生活中，很多人多个账号公用一个密码，那么假如账号信息和个人信息被泄露，那么就存在个人信息和财产受到威胁的情况！为了防止用户密码被泄露之后，很容易就被非法分子看到原始的密码，我们需要对用户的密码进行加密后再存储！明文：将原密码实际的存储到数据库中可以">
<meta property="og:type" content="article">
<meta property="og:title" content="nodejs">
<meta property="og:url" content="http://yoursite.com/2017/10/25/node/index.html">
<meta property="og:site_name" content="Hexo">
<meta property="og:description" content="搭建博客案例基本结构并渲染首页 把MVC结构搭建起来  用户注册模块的实现用户登录模块的实现登录密码MD5加密存储的实现为什么要对密码进行加密处理在现实生活中，很多人多个账号公用一个密码，那么假如账号信息和个人信息被泄露，那么就存在个人信息和财产受到威胁的情况！为了防止用户密码被泄露之后，很容易就被非法分子看到原始的密码，我们需要对用户的密码进行加密后再存储！明文：将原密码实际的存储到数据库中可以">
<meta property="og:updated_time" content="2017-10-25T12:05:40.533Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="nodejs">
<meta name="twitter:description" content="搭建博客案例基本结构并渲染首页 把MVC结构搭建起来  用户注册模块的实现用户登录模块的实现登录密码MD5加密存储的实现为什么要对密码进行加密处理在现实生活中，很多人多个账号公用一个密码，那么假如账号信息和个人信息被泄露，那么就存在个人信息和财产受到威胁的情况！为了防止用户密码被泄露之后，很容易就被非法分子看到原始的密码，我们需要对用户的密码进行加密后再存储！明文：将原密码实际的存储到数据库中可以">
  
    <link rel="alternate" href="/atom.xml" title="Hexo" type="application/atom+xml">
  
  
    <link rel="icon" href="/favicon.png">
  
  
    <link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
  
  <link rel="stylesheet" href="/css/style.css">
  

</head>

<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="/" id="logo">Hexo</a>
      </h1>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"></a>
        
          <a class="main-nav-link" href="/">Home</a>
        
          <a class="main-nav-link" href="/archives">Archives</a>
        
      </nav>
      <nav id="sub-nav">
        
          <a id="nav-rss-link" class="nav-icon" href="/atom.xml" title="RSS Feed"></a>
        
        <a id="nav-search-btn" class="nav-icon" title="Search"></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="sitesearch" value="http://yoursite.com"></form>
      </div>
    </div>
  </div>
</header>
      <div class="outer">
        <section id="main"><article id="post-node" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2017/10/25/node/" class="article-date">
  <time datetime="2017-10-25T12:04:18.200Z" itemprop="datePublished">2017-10-25</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 class="article-title" itemprop="name">
      nodejs
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <h2 id="搭建博客案例基本结构并渲染首页"><a href="#搭建博客案例基本结构并渲染首页" class="headerlink" title="搭建博客案例基本结构并渲染首页"></a>搭建博客案例基本结构并渲染首页</h2><ul>
<li>把MVC结构搭建起来</li>
</ul>
<h2 id="用户注册模块的实现"><a href="#用户注册模块的实现" class="headerlink" title="用户注册模块的实现"></a>用户注册模块的实现</h2><h2 id="用户登录模块的实现"><a href="#用户登录模块的实现" class="headerlink" title="用户登录模块的实现"></a>用户登录模块的实现</h2><h2 id="登录密码MD5加密存储的实现"><a href="#登录密码MD5加密存储的实现" class="headerlink" title="登录密码MD5加密存储的实现"></a>登录密码MD5加密存储的实现</h2><h3 id="为什么要对密码进行加密处理"><a href="#为什么要对密码进行加密处理" class="headerlink" title="为什么要对密码进行加密处理"></a>为什么要对密码进行加密处理</h3><p>在现实生活中，很多人多个账号公用一个密码，那么假如账号信息和个人信息被泄露，那么就存在个人信息和财产受到威胁的情况！<br>为了防止用户密码被泄露之后，很容易就被非法分子看到原始的密码，我们需要对用户的密码进行加密后再存储！<br>明文：将原密码实际的存储到数据库中可以直接查看用户的原始密码；<br>密文：就是将密码，加密之后再保存到数据中，这样存储方式，能有提高密码的安全性，就算数据库中的密码不小心被泄露了，非法分子，也无法直接获取到用户的原密码！</p>
<h3 id="什么是MD5加密"><a href="#什么是MD5加密" class="headerlink" title="什么是MD5加密"></a>什么是MD5加密</h3><p>MD5的全称是Message-Digest Algorithm 5（信息-摘要算法），在90年代初由MIT Laboratory for Computer Science和RSA Data Security Inc的Ronald L. Rivest开发出来，经MD2、MD3和MD4发展而来。<br>MD5加密的特性：</p>
<ul>
<li>MD5加密后输出的一般都是<code>32位长度的字符串</code></li>
<li>相同的内容使用MD5加密后，得到的内容是一致的</li>
<li>MD5加密后的字符串是无法通过算法的形式反向解密的（唯一的破解方式是暴力碰撞破解）</li>
<li>为了防止暴力碰撞破解，我们可以对需要加密的内容，进行<strong>加盐处理</strong></li>
</ul>
<blockquote>
<p>什么是加盐处理：就是在需要加密的文本内容，和一串长且复杂的文本进行拼接，这样就能防止加密后的MD5值被暴力碰撞破解。<br>为什么要加盐加密：就是为了防止用户的密码过于简单，然后我们程序通过加盐，提高了密码的复杂性，这样能够保证用户信息的安全！</p>
</blockquote>
<h3 id="在Express中使用MD5加密"><a href="#在Express中使用MD5加密" class="headerlink" title="在Express中使用MD5加密"></a>在Express中使用MD5加密</h3><ol>
<li><p>运行以下命令安装MD5加密模块：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">npm install blueimp-md5 -S</div></pre></td></tr></table></figure>
</li>
<li><p>使用方式：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">var hash = md5(&quot;value&quot;, &quot;key&quot;);</div></pre></td></tr></table></figure>
</li>
</ol>
<h2 id="HTTP协议的无状态性"><a href="#HTTP协议的无状态性" class="headerlink" title="HTTP协议的无状态性"></a>HTTP协议的无状态性</h2><ol>
<li>HTTP协议的通信模型：基于<code>请求 - 处理 - 响应</code>的！</li>
<li>由于这个通信协议的关系，导致了HTTP每个请求之间都是没有关联的，每当一个请求完成之后，服务器就忘记之前谁曾经请求过！</li>
<li>如果纯粹基于HTTP通信模型，是无法完成登录状态保持的！每次请求服务器，服务器都会把这个请求当作新请求来处理！</li>
<li>我们可以通过 cookie 技术，实现状态保持，但是由于cookie是存储在客户端的一门技术，所以安全性几乎没有，因此不要使用cookie存储敏感的数据！</li>
</ol>
<h2 id="cookie介绍"><a href="#cookie介绍" class="headerlink" title="cookie介绍"></a>cookie介绍</h2><h3 id="什么是cookie，作用是什么"><a href="#什么是cookie，作用是什么" class="headerlink" title="什么是cookie，作用是什么"></a>什么是cookie，作用是什么</h3><ul>
<li>由于<strong>Http协议是无状态</strong>的，且传统服务器<strong>只能被动的响应请求</strong>，所以，当服务器获取到请求的时候，并不知道当前请求属于哪个客户端！</li>
<li>服务器为了能够明确区分每个客户端，需要使用一些小技术，来根据不同的请求区分不同的客户端；</li>
<li>只要有请求发生，那么必然对应一个客户端，那么，我们可以在每次客户端发起请求的时候，向服务器自动发送一个标识符，告诉服务器当前是哪个客户端正在请求服务器的数据；</li>
<li>如何提供这个标识符呢？我们可以在请求头(Request Headers)中添加一个标签，叫做<code>cookie</code>，这样，每次发送请求，都会把这个cookie随同其他报文一起发送给服务器，服务器可以根据报文中的cookie，区分不同的客户端浏览器。</li>
<li>如何在客户端请求头中添加标识符？<ul>
<li>在Node中可以在<code>writeHeader</code>的时候，通过<code>Set-Cookie</code>来将cookie标识通过响应报文发送给客户端！</li>
<li>客户端也可以通过一些方式来操作自己的cookie，比如通过<code>jquery.cookie</code>这个插件！</li>
</ul>
</li>
</ul>
<h3 id="cookie的基本使用"><a href="#cookie的基本使用" class="headerlink" title="cookie的基本使用"></a>cookie的基本使用</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div></pre></td><td class="code"><pre><div class="line">var http = require(&apos;http&apos;);</div><div class="line"></div><div class="line">var server = http.createServer();</div><div class="line"></div><div class="line">server.on(&apos;request&apos;, function (req, res) &#123;</div><div class="line">    // 解析cookie</div><div class="line">    var cookies = &#123;&#125;;</div><div class="line">    var cookieStr = req.headers.cookie; // 从请求的headers中获取cookie信息</div><div class="line">    cookieStr &amp;&amp; cookieStr.split(&apos;;&apos;).forEach(function (item) &#123;</div><div class="line">        var parts = item.split(&apos;=&apos;);</div><div class="line">        cookies[parts[0].trim()] = parts[1].trim(); // 将cookie解析出来，保存到对象中</div><div class="line">    &#125;);</div><div class="line"></div><div class="line">    res.writeHeader(200, &#123;</div><div class="line">        &apos;Content-Type&apos;: &apos;text/plain; charset=utf-8&apos;,</div><div class="line">        &quot;Set-Cookie&quot;: [&apos;issend=ok&apos;, &apos;age=20&apos;]</div><div class="line">    &#125;);</div><div class="line"></div><div class="line">    if(cookies.issend ===&apos;ok&apos;)&#123;</div><div class="line">        res.end(&apos;不要太贪心哦！&apos;);</div><div class="line">    &#125;else&#123;</div><div class="line">        res.end(&apos;呐，赏你一朵小红花~~&apos;);</div><div class="line">    &#125;</div><div class="line">&#125;);</div><div class="line"></div><div class="line">server.listen(4000, function () &#123;</div><div class="line">    console.log(&apos;服务器已启动!&apos;);</div><div class="line">&#125;);</div></pre></td></tr></table></figure>
<h3 id="通过expires设置Cookie的过期时间"><a href="#通过expires设置Cookie的过期时间" class="headerlink" title="通过expires设置Cookie的过期时间"></a>通过<code>expires</code>设置Cookie的过期时间</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">// 设置 过期时间 为60秒之后</div><div class="line">// 注意：在设置过期时间的时候，需要将时间转换为 UTC 格式</div><div class="line">var expiresTime = new Date(Date.now() + 1000 * 60).toUTCString();</div><div class="line">res.writeHeader(200, &#123;</div><div class="line">  &apos;Content-Type&apos;: &apos;text/html; charset=utf-8&apos;,</div><div class="line">  &apos;Set-Cookie&apos;: [&apos;isvisit=true;expires=&apos; + expiresTime, &apos;test=OK&apos;]</div><div class="line">&#125;);</div><div class="line">res.end(&apos;&lt;h3&gt;你好，欢迎光临，送给你一个苹果！&lt;/h3&gt;&apos;);</div></pre></td></tr></table></figure>
<p><a href="http://www.wbiao.cn/cartier-watches/knowledge/article-1468.html" target="_blank" rel="external">GMT和UTC有什么区别？格林尼治标准时（GMT）与世界时（UTC）是怎么回事</a></p>
<h3 id="cookie可以被伪造，不安全"><a href="#cookie可以被伪造，不安全" class="headerlink" title="cookie可以被伪造，不安全"></a>cookie可以被伪造，不安全</h3><p>使用谷歌插件<code>edit this cookie</code>，就能伪造cookie数据！所以不要使用cookie存储敏感的数据！比如登录状态和登录信息；<br>一些敏感的数据，应该存储都服务器端！</p>
<h2 id="登录退出及状态保存"><a href="#登录退出及状态保存" class="headerlink" title="登录退出及状态保存"></a>登录退出及状态保存</h2><h3 id="使用express-session来保存登录状态"><a href="#使用express-session来保存登录状态" class="headerlink" title="使用express-session来保存登录状态"></a>使用<code>express-session</code>来保存登录状态</h3><h4 id="什么是session"><a href="#什么是session" class="headerlink" title="什么是session"></a>什么是session</h4><p>由于HTTP是无状态的，所以服务器在每次连接中持续保存客户端的私有数据，此时需要结合cookie技术，通过session会话机制，在服务器端保存每个HTTP请求的私有数据；</p>
<h4 id="session原理"><a href="#session原理" class="headerlink" title="session原理"></a>session原理</h4><p>在服务器内存中开辟一块地址空间，专门存放每个客户端私有的数据，每个客户端根据cookie中保存的私有sessionId，可以获取到独属于自己的session数据。</p>
<h4 id="在express中使用session"><a href="#在express中使用session" class="headerlink" title="在express中使用session"></a>在express中使用session</h4><ol>
<li><p>安装session模块</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">npm install express-session -S</div></pre></td></tr></table></figure>
</li>
<li><p>导入session模块</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">var session = require(&apos;express-session&apos;)</div></pre></td></tr></table></figure>
</li>
<li><p>在express中使用<code>session</code>中间件：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">// 启用 session 中间件</div><div class="line">app.use(session(&#123;</div><div class="line">  secret: &apos;keyboard cat&apos;, // 相当于是一个加密密钥，值可以是任意字符串</div><div class="line">  resave: false, // 强制session保存到session store中</div><div class="line">  saveUninitialized: false // 强制没有“初始化”的session保存到storage中</div><div class="line">&#125;))</div></pre></td></tr></table></figure>
</li>
<li><p>将私有数据保存到当前请求的session会话中：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">// 将登录的用户保存到session中</div><div class="line">req.session.user = result.dataValues;</div><div class="line">// 设置是否登录为true</div><div class="line">req.session.islogin = true;</div></pre></td></tr></table></figure>
</li>
<li><p>通过<code>destroy()</code>方法清空<code>session</code>数据：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">req.session.destroy(function(err)&#123;</div><div class="line">  if(err) throw err;</div><div class="line">  console.log(&apos;用户退出成功！&apos;);</div><div class="line">  res.redirect(&apos;/&apos;);</div><div class="line">&#125;);</div></pre></td></tr></table></figure>
</li>
</ol>
<h2 id="注销功能的实现"><a href="#注销功能的实现" class="headerlink" title="注销功能的实现"></a>注销功能的实现</h2><h2 id="使用模板引擎处理公共部分"><a href="#使用模板引擎处理公共部分" class="headerlink" title="使用模板引擎处理公共部分"></a>使用模板引擎处理公共部分</h2><h2 id="添加文章并跳转到文章详情"><a href="#添加文章并跳转到文章详情" class="headerlink" title="添加文章并跳转到文章详情"></a>添加文章并跳转到文章详情</h2><h2 id="完成文章编辑功能"><a href="#完成文章编辑功能" class="headerlink" title="完成文章编辑功能"></a>完成文章编辑功能</h2><h2 id="首页文章列表渲染和处理相对时间"><a href="#首页文章列表渲染和处理相对时间" class="headerlink" title="首页文章列表渲染和处理相对时间"></a>首页文章列表渲染和处理相对时间</h2><h2 id="使用Sql语句进行联表查询"><a href="#使用Sql语句进行联表查询" class="headerlink" title="使用Sql语句进行联表查询"></a>使用Sql语句进行联表查询</h2><h2 id="首页文章列表分页功能的实现"><a href="#首页文章列表分页功能的实现" class="headerlink" title="首页文章列表分页功能的实现"></a>首页文章列表分页功能的实现</h2><h2 id="相关文章"><a href="#相关文章" class="headerlink" title="相关文章"></a>相关文章</h2><ol>
<li><a href="http://blog.csdn.net/liangklfang/article/details/50998959" target="_blank" rel="external">node.js中express-session配置项详解</a></li>
<li><a href="http://www.cmd5.com/" target="_blank" rel="external">MD5在线生成器1</a></li>
<li><a href="http://pmd5.com/" target="_blank" rel="external">MD5在线生成器2</a></li>
<li><a href="https://github.com/blueimp/JavaScript-MD5" target="_blank" rel="external">JavaScript-MD5</a></li>
</ol>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2017/10/25/node/" data-id="cj96zu15x0000do52irlq1d8s" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
    
<nav id="article-nav">
  
    <a href="/2017/10/25/node-express/" id="article-nav-newer" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Newer</strong>
      <div class="article-nav-title">
        
          express
        
      </div>
    </a>
  
  
    <a href="/2017/10/25/nodelast/" id="article-nav-older" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Older</strong>
      <div class="article-nav-title">angular2</div>
    </a>
  
</nav>

  
</article>

</section>
        
          <aside id="sidebar">
  
    

  
    

  
    
  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Archives</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/10/">October 2017</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/08/">August 2017</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Recent Posts</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/2017/10/25/node2/">nodejs1</a>
          </li>
        
          <li>
            <a href="/2017/10/25/node-express/">express</a>
          </li>
        
          <li>
            <a href="/2017/10/25/node/">nodejs</a>
          </li>
        
          <li>
            <a href="/2017/10/25/nodelast/">angular2</a>
          </li>
        
          <li>
            <a href="/2017/10/22/text/">(no title)</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      &copy; 2017 John Doe<br>
      Powered by <a href="http://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer>
    </div>
    <nav id="mobile-nav">
  
    <a href="/" class="mobile-nav-link">Home</a>
  
    <a href="/archives" class="mobile-nav-link">Archives</a>
  
</nav>
    

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>


  <link rel="stylesheet" href="/fancybox/jquery.fancybox.css">
  <script src="/fancybox/jquery.fancybox.pack.js"></script>


<script src="/js/script.js"></script>

  </div>
</body>
</html>